﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace SimpleTools.Net.SimpleServer.UDP
{
    public class GetInterfaces
    {
        /// <summary>
        /// 获取实现了指定接口的类字典,[小写类名，Interfaces]
        /// </summary>
        /// <param name="iType">接口type</param>
        /// <param name="methodName">需要调用的方法名称</param>
        /// <param name="actionType">需要查找的命名空间，一个命名空间只要传入一个类即可</param>
        /// <returns></returns>
        public static Dictionary<string, InterfaceClass> GetIs(Type iType, string methodName, params Type[] actionTypes)
        {
            var dic = new Dictionary<string, InterfaceClass>();
            foreach (Type item in actionTypes)
            {
                Find(ref dic, iType, methodName, item);
            }
            return dic;
        }

        private static void Find(ref Dictionary<string, InterfaceClass> dic, Type iType, string methodName, Type actionType)
        {
            Type[] types = Assembly.GetAssembly(actionType).GetTypes();
            foreach (Type item in types)
            {
                if (item.IsInterface) continue;//判断是否是接口
                Type[] ins = item.GetInterfaces();
                foreach (Type ty in ins)
                {
                    if (ty == iType && item.Namespace == actionType.Namespace)
                    {
                        dic.Add(item.Name.ToLower(), new InterfaceClass(Activator.CreateInstance(item), item.GetMethod(methodName)));
                    }
                }
            }
        }

        public static Dictionary<string, InterfaceClass> GetIs(Type iType, string methodName, Assembly assembly, params string[] namespaces)
        {
            var dic = new Dictionary<string, InterfaceClass>();
            foreach (var item in namespaces)
            {
                Find(ref dic, iType, assembly.GetTypes(), methodName, item);
            }
            return dic;
        }

        private static void Find(ref Dictionary<string, InterfaceClass> dic, Type iType, Type[] types, string methodName, string namespace_)
        {
            foreach (Type item in types)
            {
                if (item.IsInterface) continue;//判断是否是接口
                Type[] ins = item.GetInterfaces();
                foreach (Type ty in ins)
                {
                    if (ty == iType && item.Namespace == namespace_)
                    {
                        dic.Add(item.Name.ToLower(), new InterfaceClass(Activator.CreateInstance(item), item.GetMethod(methodName)));
                    }
                }
            }

        }
        public class InterfaceClass
        {
            public object o;
            public MethodInfo MethodInfo;
            public InterfaceClass(object o, MethodInfo methodInfo)
            {
                this.o = o;
                MethodInfo = methodInfo;
            }
            public void Invoke(ref object[] ps)
            {
                MethodInfo.Invoke(o, ps);
            }
        }
    }
}
